//
//  EXObjectStore.h
//  ORM
//
//  Created by PH on 21.12.09.
//  Copyright 2009-2010 Codesign. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "ORMKeyValueStore.h"
#import "EXMappableObject.h"
#import "EXQuery.h"
#import "EXTransaction.h"
#import "EXObjectReferenceInCollection.h"
#import "EXPredicate.h"
#import "EXObjectStoreDelegate.h"
#import "EXObjectStoreExt.h"

@interface EXObjectStore : NSObject {
	NSObject<ORMKeyValueStore>* KVStore;
	NSMutableDictionary* mapOfIDs;
	NSMutableDictionary* cache;
	EXTransaction* currentTransaction;
	NSObject<EXObjectStoreDelegate>* delegate;
	//NSMutableArray* zombies;
}

@property (retain) EXTransaction* currentTransaction;
@property (retain) NSObject<ORMKeyValueStore>* KVStore;
@property (retain) NSMutableDictionary* mapOfIDs;
@property (retain) NSMutableDictionary* cache;
@property (nonatomic, retain) NSObject<EXObjectStoreDelegate>* delegate;

- (id)initWithPath:(NSString*)path;
- (id)initWithPath:(NSString*)path autosync:(BOOL)_autosync;
- (BOOL)storeObject:(NSObject<EXMappableObject>*)object;
- (BOOL)removeObject:(NSObject<EXMappableObject>*)object;
- (NSArray*)objectsOfClass:(Class)cls;
- (NSArray*)objectsOfClass:(Class)cls sortedByProperty:(NSString*)propertyName;
- (NSArray*)objectsOfClass:(Class)cls filter:(EXQuery*)query;
- (NSArray*)proxiesOfClass:(Class)cls;
- (id)objectWithObjectID:(NSString*)objectID;
- (EXTransaction*)beginTransaction;
- (BOOL)createIndexOnField:(NSString*)fieldName;
- (BOOL)createIndexOnField:(NSString*)fieldName rebuild:(BOOL)rebuild;
- (id)singletonOfClass:(Class)cls createIfNotFound:(BOOL)createIfNotFound;
- (EXPredicate*)predicateWithClass:(Class)cls;
- (EXPredicate*)predicateWithClass:(Class)cls predicate:(NSPredicate*)_predicate;
- (NSArray*)objectsWithPredicate:(EXPredicate*)predicate;
- (NSArray*)proxiesWithPredicate:(EXPredicate*)predicate;
- (NSString*)IDOfObject:(NSObject<EXMappableObject>*)object;
- (EXObjectStore<EXObjectStoreExt>*)ext;
- (void)close;
- (void)bindObject:(NSObject<EXMappableObject>*)object toObjectID:(NSString*)objectID;

// internal methods

- (NSString*)uniqueKey;
- (void)discardObject:(NSObject<EXAbstractMappableObject>*)object;
- (void)discardObjectGC:(NSObject<EXAbstractMappableObject>*)object;
- (id)decodePropertyOfType:(NSString*)type data:(NSData*)data lazyCollections:(BOOL)lazyCollections processedObjects:(NSMutableDictionary*)processedObjects;
- (BOOL)storeObject:(NSObject<EXMappableObject>*)object createTransaction:(BOOL)createTransaction processedObjects:(NSMutableSet*)processedObjects;
- (BOOL)removeObject:(NSObject<EXMappableObject>*)object createTransaction:(BOOL)createTransaction;
- (void)objectsOfClass:(Class)cls createTransaction:(BOOL)createTransaction includeSubclasses:(BOOL)includeSubclasses results:(NSMutableArray*)results processedObjects:(NSMutableDictionary*)processedObjects;
- (void)objectsOfClass:(Class)cls createTransaction:(BOOL)createTransaction includeSubclasses:(BOOL)includeSubclasses results:(NSMutableArray*)results condBlock:(void(^)(void*))condBlock processedObjects:(NSMutableDictionary*)processedObjects;
- (void)proxiesOfClass:(Class)cls createTransaction:(BOOL)createTransaction includeSubclasses:(BOOL)includeSubclasses results:(NSMutableArray*)results proxies:(NSMutableDictionary*)proxies condBlock:(void(^)(void*))condBlock;
- (NSObject<EXMappableObject>*)objectWithObjectID:(NSString*)objectID lazyCollections:(BOOL)lazyCollections;
- (NSObject<EXMappableObject>*)objectWithObjectID:(NSString*)objectID lazyCollections:(BOOL)lazyCollections createTransaction:(BOOL)createTransaction processedObjects:(NSMutableDictionary*)processedObjects;
+ (NSSet*)subclassesOfClass:(Class)cls;
//- (NSObject<ORMKeyValueStore>*)KVStore;
- (NSArray*)objectsOfClass:(Class)cls filter:(EXQuery*)query createTransaction:(BOOL)createTransaction;
- (EXObjectReferenceInCollection*)encodeMappableObject:(id)object processedObjects:(NSMutableSet*)processedObjects;
- (NSArray*)objectsWithPredicate:(EXPredicate*)predicate createTransaction:(BOOL)createTransaction processedObjects:(NSMutableDictionary*)_processedObjects;

@end
